package com.ft.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

/**
 * @author mdc mdc@comit.com.cn
 * maidachao comit
 * -ft-
 */
@Configuration
/*@MapperScan(basePackages = "com.ft.modules.*.mapper**", sqlSessionFactoryRef = "primarySqlSessionFactory")*/
public class DruidDBConfig {

	/**
	 * dao层的包路径
	 */
	static final String PACKAGE = "com.ft.modules.*.mapper**";

	//分页，
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
		return paginationInterceptor;
	}
	/**
	 * mapper文件的相对路径
	 */
	private static final String MAPPER_LOCATION = "classpath:mapper/**/*.xml";
	private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
	
	@Value("${spring.datasource.primary.url}")
	private String dbUrl;

	@Value("${spring.datasource.primary.username}")
	private String username;

	@Value("${spring.datasource.primary.password}")
	private String password;

	@Value("${spring.datasource.primary.driverClassName}")
	private String driverClassName;

	@Value("${spring.datasource.primary.initialSize}")
	private int initialSize;

	@Value("${spring.datasource.primary.minIdle}")
	private int minIdle;

	@Value("${spring.datasource.primary.maxActive}")
	private int maxActive;

	@Value("${spring.datasource.primary.maxWait}")
	private int maxWait;

	@Value("${spring.datasource.primary.timeBetweenEvictionRunsMillis}")
	private int timeBetweenEvictionRunsMillis;

	@Value("${spring.datasource.primary.minEvictableIdleTimeMillis}")
	private int minEvictableIdleTimeMillis;

	@Value("${spring.datasource.primary.validationQuery}")
	private String validationQuery;

	@Value("${spring.datasource.primary.testWhileIdle}")
	private boolean testWhileIdle;

	@Value("${spring.datasource.primary.testOnBorrow}")
	private boolean testOnBorrow;

	@Value("${spring.datasource.primary.testOnReturn}")
	private boolean testOnReturn;

	@Value("${spring.datasource.primary.poolPreparedStatements}")
	private boolean poolPreparedStatements;

	@Value("${spring.datasource.primary.maxPoolPreparedStatementPerConnectionSize}")
	private int maxPoolPreparedStatementPerConnectionSize;

	@Value("${spring.datasource.primary.filters}")
	private String filters;

	@Value("{spring.datasource.primary.connectionProperties}")
	private String connectionProperties;


	@Primary
	@Bean(name="primaryDataSource")
	public DataSource dataSource() {
		DruidDataSource datasource = new DruidDataSource();

		datasource.setUrl(this.dbUrl);
		datasource.setUsername(username);
		datasource.setPassword(password);
		datasource.setDriverClassName(driverClassName);

		// configuration
		datasource.setInitialSize(initialSize);
		datasource.setMinIdle(minIdle);
		datasource.setMaxActive(maxActive);
		datasource.setMaxWait(maxWait);
		datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		datasource.setValidationQuery(validationQuery);
		datasource.setTestWhileIdle(testWhileIdle);
		datasource.setTestOnBorrow(testOnBorrow);
		datasource.setTestOnReturn(testOnReturn);
		datasource.setPoolPreparedStatements(poolPreparedStatements);
		datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
		try {
			datasource.setFilters(filters);
		} catch (SQLException e) {
			logger.error("druid configuration initialization filter", e);
		}
		datasource.setConnectionProperties(connectionProperties);

		return datasource;
	}

	// 创建该数据源的事务管理
	@Primary
	@Bean(name = "primaryTransactionManager")
	public DataSourceTransactionManager primaryTransactionManager() throws SQLException {
		return new DataSourceTransactionManager(dataSource());
	}

	// 创建Mybatis的连接会话工厂实例
	@Primary
	@Bean(name = "primarySqlSessionFactory")
	public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource) throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		//不能去掉，去掉就分页失败
		MybatisConfiguration configuration = new MybatisConfiguration();
		configuration.setJdbcTypeForNull(JdbcType.NULL);
		configuration.setMapUnderscoreToCamelCase(true);
		configuration.setCacheEnabled(false);
		sessionFactory.setConfiguration(configuration);

		sessionFactory.setDataSource(primaryDataSource);  // 设置数据源bean
		sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
				.getResources(DruidDBConfig.MAPPER_LOCATION));  // 设置mapper文件路径
		//添加分页功能
		sessionFactory.setPlugins(new Interceptor[]{
				paginationInterceptor()
		});
		return sessionFactory.getObject();
	}

}
